#ifndef _COM_DEF_H_
#define _COM_DEF_H_

#include "stdint.h"

#define COM_DAT_NULL             0x7FFF

typedef enum
{
	COM_RX_IDLE, //!< Receiver is in idle state.
	COM_RX_RCV,  //!< Frame is beeing receiving.
	COM_RX_RCVEND, //!< Frame is beeing receive end.
	COM_RX_WAIT,  //!< Frame is send at master mode.
	COM_RX_TIMEOUT //!< Time out ,Send a command and no data return after 500ms( --> system timer)

} com_rcv_state_type;

typedef enum
{
	COM_TX_IDLE, /*!< Transmitter is in idle state. */
	COM_TX_XMIT  /*!< Transmitter is in transfer state. */
} com_snd_state_type;

typedef enum
{
	COM_PAR_NONE_1S, /*!< No parity. 1 stop bit*/
	COM_PAR_NONE_2S, /*!< No parity. 2 stop bit*/
	COM_PAR_ODD,  /*!< Odd parity. */
	COM_PAR_EVEN  /*!< Even parity. */
} com_parity_type;

typedef enum     /*!signal mode data format*/
{
	COM_DAT_DATA = 0,
	COM_DAT_STRING,
} com_data_mode_type;

typedef union
{
	uint32_t St;

	struct
	{
		uint8_t run_en; /*port work st*/
		uint8_t port_st; /*found data*/
		uint8_t cycle_mode; /*cycle or signal mode*/
		uint8_t err_hal;
	} bits;
} com_state_type;


typedef struct
{
	void(*rx_cmd)(uint8_t xEnable);  //rx接收开关
	void(*tx_cmd)(uint8_t xEnable);  //tx发送开关
	void(*timer_handle)(void);       //延时处理
	/*app interface*/
	uint8_t(*idle_check)(void);       //tx and rx line idle check
	int16_t(*wait_for_idle)(uint16_t time_out); //wait for tx and rx line idle
	void(*rcv_st_clr)(void);          //clr state for rx line

	int16_t(*signal_rcv_data)(uint8_t *p_dat, uint16_t buff_size);
	int16_t(*signal_snd_data)(const uint8_t *p_dat, uint16_t len);
	int16_t(*signal_snd_string)(const uint8_t *p_dat);

	void(*cycle_snd_byte)(uint8_t ch);
	int16_t(*cycle_rcv_byte)(void);
	void(*cycle_snd_string)(const uint8_t * str);
	void(*cycle_snd_data)(const uint8_t * dat, uint16_t len);
	uint16_t(*cycle_rcv_multi)(uint8_t * dat, uint16_t buff_size);
	uint16_t(*cycle_rcv_line)(uint8_t * dat, uint16_t len_max);
	uint16_t(*cycle_rcv_end_4B)(uint8_t * dat, uint16_t len_max, uint32_t symbol);
	uint16_t(*cycle_rcv_end_3B)(uint8_t * dat, uint16_t len_max, uint32_t symbol);
	uint16_t(*cycle_rcv_end_2B)(uint8_t * dat, uint16_t len_max, uint16_t symbol);
	uint16_t(*cycle_rcv_remain_amount)(void); //返回剩余未读取数据个数
	uint16_t(*cycle_snd_remain_amount)(void);
} com_fun_type;

typedef struct
{
	com_state_type St;
	com_data_mode_type dat_mode; //just for signal mode

	//数据模式结束判定
	uint16_t rcv_end_time_cnt;
	uint16_t rcv_end_time_sv;   //用于判定报文结束的计时设定值，计时到设立结束标志并根据master/slave模式发送事件

	//状态计时
	uint16_t act_time_cnt;
	uint16_t act_time_max;
	uint16_t idle_time_cnt;
	uint16_t master_wait_time_cnt;
	uint16_t master_wait_time_sv; //master进入等待状态后计时设定值，达到改值发送超时事件

	uint8_t b_timer_on;
	uint8_t b_master_mode;    //库文件内，master mode 接收结束计时和超时等待有区别，其他同slave
	uint8_t rcv_end_char;     //接收结束符号 0表示不启用，启用结束符时应将rcv_end_time_sv设置的足够大
	uint8_t rcv_start_char;   //接收起始符号 0表示不启用 
	uint32_t rcv_squence;     //接收数据序列，最新数据在最低位

	volatile com_snd_state_type snd_st; //just for signal mode
	volatile com_rcv_state_type rcv_st; //just for signal mode

	/*buff size*/
	uint16_t rx_buff_size;
	uint16_t tx_buff_size;

	/*buff index*/
	uint16_t index_tx_fill; //cycle待填充位置-signal已填充个数
	volatile uint16_t index_tx_send; //cycle待发送位置-signal已发送个数
	uint16_t index_rx_rcv;  //cycle待填充位置-signal已填充个数
	uint16_t index_rx_get;  //cycle待读取位置-signal已读取个数

	/*buff point*/
	uint8_t *rx_buff; //work in cycle mode and signal mode
	uint8_t *tx_buff; //just for cycle mode

	/*tx data point*/
	uint8_t *p_tx; //just for signal mode

	/*任务事件*/
	uint16_t os_event_timeout;
	uint16_t os_event_rcv_end;
	uint16_t rcv_end_keep_sv; //master-mode接收结束后保持sv后发送事件, slave-mode接收结束后立即发送事件
	uint16_t rcv_end_keep_cnt;
	uint32_t usr_timer_cnt;   //定时器中断中自由计数
	/*interface*/
	void(*rx_call_back)(uint8_t ch); //接收数据回调, 用在循环接收模式
	void(*os_event_send)(uint16_t event); //os事件支持接口

	/*app fun*/
	const com_fun_type *fun;
} com_obj_type;

/*common function*/
void com_ext_wait(uint16_t ms);
void com_tx_cmd(com_obj_type *com, uint8_t en_or_dis);
void com_rx_cmd(com_obj_type *com, uint8_t en_or_dis);
uint8_t com_idle_check(com_obj_type *com);
int16_t com_wait_for_idle(com_obj_type *com, uint16_t time_out);
void com_master_mode_en(com_obj_type *com);
void com_master_mode_dis(com_obj_type *com);
int16_t com_rcv_st_clr(com_obj_type *com);

/*timer manager*/
void com_end_time_set(com_obj_type *com, uint16_t sv);
void com_wait_time_set(com_obj_type *com, uint16_t sv);
void com_timer_en(com_obj_type *com);
void com_timer_dis(com_obj_type *com);
void com_timer_run(com_obj_type *com);
uint16_t com_timer_cal(uint32_t baud, uint16_t bits, uint16_t min, uint16_t max); //base on 10us

/*cycle mode function*/
// send data to tx buffer, if buffer is full, call com_ext_wait
void com_cycle_snd_string(com_obj_type *com, const uint8_t * str);
void com_cycle_snd_data(com_obj_type *com, const uint8_t * dat, uint16_t len);
void com_cycle_snd_byte(com_obj_type *com, uint8_t ch);
// read data from rx buffer
int16_t com_cycle_rcv_byte(com_obj_type *com);
uint16_t com_cycle_rcv_multi(com_obj_type *com, uint8_t * dat, uint16_t buff_size);
uint16_t com_cycle_rcv_line(com_obj_type *com, uint8_t * dat, uint16_t len_max); // 末尾补0，实际缓冲数应为len_max+1
uint16_t com_cycle_rcv_end_4B(com_obj_type *com, uint8_t * dat, uint16_t len_max, uint32_t symbol); //符号最高字节不允许为0
uint16_t com_cycle_rcv_end_3B(com_obj_type *com, uint8_t * dat, uint16_t len_max, uint32_t symbol); //符号最高字节不允许为0
uint16_t com_cycle_rcv_end_2B(com_obj_type *com, uint8_t * dat, uint16_t len_max, uint16_t symbol); //符号最高字节不允许为0
uint16_t com_cycle_rcv_remain_amount(com_obj_type *com);
uint16_t com_cycle_snd_remain_amount(com_obj_type *com);

/*signal mode function*/
int16_t com_signal_snd_string(com_obj_type *com, const uint8_t *p_dat);
int16_t com_signal_snd_data(com_obj_type *com, const uint8_t *p_dat, uint16_t len);
int16_t com_signal_rcv_data(com_obj_type *com, uint8_t *p_dat, uint16_t buff_size);

#endif /* _COM_DEF_H_ */
